package com.clss.emergencycall.utils;

import android.media.MediaRecorder;
import android.os.Handler;

import java.io.File;
import java.io.IOException;

/**
 * Created by Administrator on 2017/6/14.
 */

public class AudioRecoderUtils {
    private final String TAG = "AudioRecoderUtils";

    //文件路径
    private String filePath;
    //文件夹路径
    private String FolderPath;
    private String fileName;

    private MediaRecorder mMediaRecorder;
    public static final int MAX_LENGTH = 1000 * 60 * 60 * 5;// 最大录音时长1000*60*10;

    private OnAudioStatusUpdateListener audioStatusUpdateListener;
    private boolean mStartNewFile = false;
    private boolean mIsRecording = false;

    /**
     * 文件存储默认sdcard/record
     */
    public AudioRecoderUtils() {
        //默认保存路径为
        this(SdCard.getAudio() + "/");
    }

    public AudioRecoderUtils(String filePath) {
        File path = new File(filePath);
        if (!path.exists()) {
            path.mkdirs();
        }
        this.FolderPath = filePath;
    }

    public String setFileName(String fileName) {
        this.fileName = fileName + ".aac";
        this.filePath = FolderPath + this.fileName;
        mStartNewFile = true;
        return filePath;
    }

    private long startTime;
    private long endTime;


    /**
     * 开始录音 使用amr格式
     * 录音文件
     */
    public void startRecord() {
        mIsRecording = true;
        // 开始录音
        /* ①Initial：实例化MediaRecorder对象 */
        if (mMediaRecorder == null) {
            Lg.i(TAG, "stopRecord: new MediaRecorder()");
            mMediaRecorder = new MediaRecorder();
        }
        try {
            /* ②setAudioSource/setVedioSource */

//                mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
		mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_UPLINK);//错误无法使用
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_DOWNLINK);//错误无法使用
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);//错误无法使用
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
//            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.REMOTE_SUBMIX);

            /* ②设置音频文件的编码：AAC/AMR_NB/AMR_MB/Default 声音的（波形）的采样 */
//		mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
            /*
             * ②设置输出文件的格式：THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
             * ，H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
             */
//		mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

            if (!mStartNewFile) {
                fileName = System.currentTimeMillis() + ".aac";
                filePath = FolderPath + fileName;
            }
            /* ③准备 */
            mMediaRecorder.setOutputFile(filePath);
            mMediaRecorder.setMaxDuration(MAX_LENGTH);
            mMediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }

        try {
            Lg.i(TAG, "stopRecord: start()");
            mMediaRecorder.start();
        } catch (Exception ignored) {
            Lg.e(TAG, "捕捉到了录音的异常");
            mMediaRecorder = new MediaRecorder();
            if (mLisener != null) {
                mLisener.startAudioFails(ignored);
            }
        }
        /* ④开始 */
//		mMediaRecorder.start();
        // AudioRecord audioRecord.
        /* 获取开始时间* */
        startTime = System.currentTimeMillis();
        updateMicStatus();
    }

    /**
     * 停止录音
     */
    public long stopRecord() {
        mIsRecording = false;
        if (mMediaRecorder == null) {
            return 0L;
        }
        endTime = System.currentTimeMillis();
        mMediaRecorder.setOnErrorListener(null);
        mMediaRecorder.setOnInfoListener(null);
        mMediaRecorder.setPreviewDisplay(null);
        try {
            Lg.i(TAG, "stopRecord: mMediaRecorder.stop()");
            mMediaRecorder.stop();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RuntimeException e) {
            //间隔时间太短 RuntimeException: stop failed. 解决方法 调用stop()之前将OnErrorListener、OnInfoListener和PreviewDisplay置空
            e.printStackTrace();
        }

        mMediaRecorder.reset();
        mMediaRecorder.release();
        mMediaRecorder = null;
        Lg.i(TAG, "stopRecord: release");
        long duration = endTime - startTime;
        if (duration < 2000) {
            deleteCancelRecordFile();
            audioStatusUpdateListener.onShort();
            return duration;
        }
        audioStatusUpdateListener.onStop(fileName, filePath, System.currentTimeMillis() - startTime);
        filePath = "";
        fileName = "";
        return endTime - startTime;
    }

    /**
     * 取消录音
     */
    public void cancelRecord() {
        mIsRecording = false;
        try {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
        } catch (RuntimeException e) {
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
        deleteCancelRecordFile();
        audioStatusUpdateListener.onCancle();

    }

    private void deleteCancelRecordFile() {
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        filePath = "";
    }

    private final Handler mHandler = new Handler();
    private Runnable mUpdateMicStatusTimer = this::updateMicStatus;


    private int BASE = 1;
    private int SPACE = 100;// 间隔取样时间

    public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
        this.audioStatusUpdateListener = audioStatusUpdateListener;
    }


    /**
     * 更新麦克状态
     */
    private void updateMicStatus() {

        if (mMediaRecorder != null) {
            double ratio = (double) mMediaRecorder.getMaxAmplitude() / BASE;
            double db = 0;// 分贝
            if (ratio > 1) {
                db = 20 * Math.log10(ratio);
//				Lg.i(TAG, "---updateMicStatus===" + db);
                if (null != audioStatusUpdateListener) {
                    audioStatusUpdateListener.onUpdate(db, System.currentTimeMillis() - startTime);
                }
            }
            mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
        }
    }

    public boolean isRecording() {
        return mIsRecording;
    }

    public interface OnAudioStatusUpdateListener {

        /**
         * 录音中...
         *
         * @param db   当前声音分贝
         * @param time 录音时长
         */
        void onUpdate(double db, long time);

        /**
         * 停止录音
         *
         * @param filePath 保存路径
         */
        void onStop(String name, String filePath, long time);

        void onCancle();

        void onShort();
    }


    /**
     * z这个单独给start异常捕捉
     */
    public interface ExceptionLisener {
        void startAudioFails(Exception e);
    }

    private ExceptionLisener mLisener;

    public void setExceptionLisener(ExceptionLisener lisener) {
        mLisener = lisener;
    }
}
